package com.ctcc.util;

import com.alibaba.fastjson.JSONObject;
import com.ctcc.entity.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.cache.Cache;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutionException;

import static com.ctcc.util.Const.appIdtest;
import static com.ctcc.util.Const.secrettest;

@Service
public class AccessTokenService {
	private static TeamAccessToken teamAccessToken = null;
	@Autowired ConfigUtils configUtils;

	@Autowired
	Cache<String,String> tokenCache;

	@Autowired
	ObjectMapper objectMapper;

	@Autowired
	OkHttpClient okHttpClient;

	public TeamAccessToken getTeamAccessToken() {
		if (teamAccessToken == null || teamAccessToken.isExpire()) {
			synchronized (AccessTokenService.class) {
				if (teamAccessToken == null || teamAccessToken.isExpire()) {
					TeamAccessTokenParam vo = new TeamAccessTokenParam();
					// 审批appid
					//vo.setAppId(Const.appId);
					//测试的
					vo.setAppId(appIdtest);
					// 随机字符串
					//vo.setNonceStr(RandomUtils.randomKey(10));
					// unix 时间戳
					vo.setTimestamp(System.currentTimeMillis() + "");
					// 签名(appid，随机字符串、unix 时间戳、开发者screct)
					//vo.setSignature(SignUtils.sign(vo.getAppId(), vo.getNonceStr(), vo.getTimestamp(),
					//		Const.secrettest));
					//测试的
					vo.setSignature(SignUtils.sign(vo.getAppId(), vo.getNonceStr(), vo.getTimestamp(),
							secrettest));


					String body = HttpUtils.postJson(
							Const.host + "/gateway/oauth2/token/getAccessToken",
							/*/gateway/oauth2/token/getAccessToken,*/
							vo);
					System.out.println(body);
					// body对象：accessToken、createTime（创建时间）、expire（是否到期）、expireIn（有效时间）、refreshToken（刷新的token）
					JSONObject res = JSONObject.parseObject(body);
					if (res != null && res.getBooleanValue("success") && res.getJSONObject("data") != null) {
						// access_token
						teamAccessToken = res.getJSONObject("data").toJavaObject(TeamAccessToken.class);
					}
				}
			}

		}
		return teamAccessToken;
	}

	public String getToken() throws IOException, ExecutionException {

		return tokenCache.get("accessToken", () -> {
            Request.Builder requestBuilder = new Request.Builder();
            HttpUrl.Builder urlBuilder = new HttpUrl.Builder();
            //https://www.yunzhijia.com/gateway/oauth2/token/getAccessToken
            urlBuilder.scheme("https");
            urlBuilder.host("www.yunzhijia.com");
            urlBuilder.addPathSegment("gateway");
            urlBuilder.addPathSegment("oauth2");
            urlBuilder.addPathSegment("token");
            urlBuilder.addPathSegment("getAccessToken");

            requestBuilder.url(urlBuilder.build());
            System.out.println("url-----" + urlBuilder.build().url().toString());
            TokenEntity tokenEntity = new TokenEntity();
            //测试圈轻应用
            /*tokenEntity.setAppId(appIdtest);
            tokenEntity.setScope("app");
            tokenEntity.setSecret(secrettest);*/

			tokenEntity.setAppId("500043743");
            tokenEntity.setScope("app");
            tokenEntity.setSecret("5wDPntzs8slhy9s4qVxZ");

            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
            String time = df.format(new Date());
            long timestamp = df.parse(time).getTime();
            tokenEntity.setTimestamp(String.valueOf(timestamp));
            String body = objectMapper.writeValueAsString(tokenEntity);
            requestBuilder.post(RequestBody.create(MediaType.parse("application/json"), body));

            Response response = okHttpClient.newCall(requestBuilder.build()).execute();
            ResponseBody responseBody = response.body();
            if (response.isSuccessful() && responseBody != null) {
                TokenBody tokenBody = objectMapper.readValue(responseBody.byteStream(), TokenBody.class);
                return tokenBody.getData().getAccessToken();
            } else {
                return null;
            }
        });

	}
	
	public TeamAccessToken refreshToken() {
		TeamAccessToken t = getTeamAccessToken();
		if(t==null){
			return null;
		}
		RefreshTokenParam vo = new RefreshTokenParam();
		vo.setAppId(configUtils.getAppId());
		vo.setNonceStr(RandomUtils.randomKey(10));
		vo.setTimestamp(System.currentTimeMillis() + "");
		vo.setRefreshToken(t.getRefreshToken());
		vo.setSignature(SignUtils.sign(vo.getAppId(), vo.getNonceStr(), vo.getTimestamp(),vo.getRefreshToken(),
				configUtils.getSecret()));
		String body = HttpUtils.postJson(
				ConfigUtils.getString(Const.host) + "/gateway/oauth2/token/refreshToken",
				vo);
		System.out.println(body);
		JSONObject res = JSONObject.parseObject(body);
		if (res != null && res.getBooleanValue("success") && res.getJSONObject("data") != null) {
			teamAccessToken = res.getJSONObject("data").toJavaObject(TeamAccessToken.class);
		}
		return teamAccessToken;
	}

	/**
	 * 获取当前用户信息
	 * @return
	 * @throws IOException
	 * @throws ExecutionException
	 */
	public UserInfoBody.DataBean getUserInfo(String Token, String Ticket) throws IOException, ExecutionException {
		Request.Builder requestBuilder = new Request.Builder();
		HttpUrl.Builder urlBuilder = new HttpUrl.Builder();
		//https://www.yunzhijia.com/gateway/oauth2/token/getAccessToken
		urlBuilder.scheme("https");
		urlBuilder.host("www.yunzhijia.com");
		urlBuilder.addPathSegment("gateway");
		urlBuilder.addPathSegment("ticket");
		urlBuilder.addPathSegment("user");
		urlBuilder.addPathSegment("acquirecontext");
		urlBuilder.addQueryParameter("accessToken",Token);
		requestBuilder.url(urlBuilder.build());
		System.out.println(("url-----" + urlBuilder.build().url().toString()));
		TicketEntity ticketEntity = new TicketEntity();
		//测试圈轻应用
		/*ticketEntity.setAppid(appIdtest);
		ticketEntity.setTicket(Ticket);*/

		//正式的Appid


		ticketEntity.setAppid("500043743");
		ticketEntity.setTicket(Ticket);

		String body = objectMapper.writeValueAsString(ticketEntity);
		requestBuilder.post(RequestBody.create(MediaType.parse("application/json"), body));

		Response response = okHttpClient.newCall(requestBuilder.build()).execute();
		ResponseBody responseBody = response.body();
		if (response.isSuccessful() && responseBody != null) {
			UserInfoBody userInfoBody = objectMapper.readValue(responseBody.byteStream(), UserInfoBody.class);
			return userInfoBody.getData();
		} else {
			return null;
		}
	}

}
